#pragma once

#include "const.h"
#include "MsgNode.h"

#include <boost/asio.hpp>
#include <string>
#include <queue>
#include <mutex>
#include <memory>


class CServer;
class LogicSystem;


class CSession : public std::enable_shared_from_this<CSession>
{
public:
	CSession(boost::asio::io_context& ioc, CServer* server);
	~CSession();

	boost::asio::ip::tcp::socket& getSocket();
	std::string& getUuid();
	std::shared_ptr<CSession> SharedSelf();

	void start();
	void asyncReadHead(int total_len);
	void asyncReadBody(int length);
	void Send(std::string msg, unsigned short msg_id);
	void Send(char* msg, unsigned short max_len, unsigned short msg_id);
	void handleWrite(const boost::system::error_code& err, std::shared_ptr<CSession> shared_self);
	

	void Close();

private:
	// 读取完成长度
	void asyncReadFull(size_t max_len, std::function<void(const boost::system::error_code&, size_t)> handler);
	// 读取指定长度的字节数
	void asyncReadLen(size_t read_len, size_t total_len, std::function<void(const boost::system::error_code&, size_t)> handler);

private:
	boost::asio::ip::tcp::socket m_socket;
	std::string m_uuid; // 连接唯一标识uuid
	char m_data[MAX_LENGTH];
	CServer* m_server;
	bool m_b_close;
	// 队列可以保证异步操作的时序性
	std::queue<std::shared_ptr<SendNode>> m_send_queue;
	std::mutex m_send_mtx;
	bool m_b_head_parse;
	std::shared_ptr<RecvNode> m_recv_msg_node; // 接受到的消息结点
	std::shared_ptr<MsgNode> m_recv_head_node; // 接受到的头部结点

};

class LogicNode
{
	friend class LogicSystem;
public:
	LogicNode(std::shared_ptr<CSession> session, std::shared_ptr<RecvNode> recvnode);

private:
	std::shared_ptr<CSession> m_session;
	std::shared_ptr<RecvNode> m_recvnode;
};


